/**
*    Copyright (C) 2008  Chase Kernan 
*    chase.kernan@gmail.com
*
*    This program is free software: you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation, either version 3 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License
*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
* 
**/

package com.chasekernan.hxnova.utils;

/**
    Basic class with a x and y component that can be expanded into 3D
 **/
class Vector {
    
    /**
        Tolerance for checking if 2 vectors are equal.
    **/
    public static inline var TOLERANCE : Float = 0.01;
    
    public var x : Float;
    public var y : Float;
    
    public function new(?x = 0.0, ?y = 0.0) {
        this.x = x;
        this.y = y;
    }
    
    public inline function distanceTo(v : Vector) : Float {
        return Math.sqrt((x - v.x) * (x - v.x) + (y - v.y) * (y - v.y));
    }
    
    public inline function distanceSquaredTo(v : Vector) : Float {
        return (x - v.x) * (x - v.x) + (y - v.y) * (y - v.y);
    }
    
    public function getSub(v : Vector) : Vector {
        return new Vector(x - v.x, y - v.y);
    }
    
    public function getAdd(v : Vector) : Vector {
        return new Vector(x + v.x, y + v.y);
    }
    
    public function getAngle() : Float {
        return Math.atan2(y, x);
    }
    
    public function equals(v : Vector) : Bool {
        return distanceTo(v) <= TOLERANCE;
    }
    
    public function clone() : Vector {
        return new Vector(x, y);
    }
    
    public function dotProduct(v : Vector) : Float {
        return x * v.x + y * v.y;
    }
    
    public function getScale(k : Float) : Vector {
        return new Vector(k * x, k * y);
    }
    
    public static inline function fromAngle(angle : Float, length : Float) 
                                  : Vector {
        return new Vector(Math.cos(angle) * length, Math.sin(angle) * length);
    }
    
    public function toString() : String {
        return "[Vector x=" + x + " y=" + y + "]";
    }
}